﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data;

namespace SPA_Prototype.Model
{
    public enum TABLE_TYPE { MAIN, DETAILS };
    public class BillManagement
    {
        
        private DatabaseDataSet _Dataset;
        public DatabaseDataSet.BillDetailsTableDataTable _DataTable_Details;
        private DatabaseDataSet.BillMainTableDataTable _DataTable_Main;
        private DatabaseDataSetTableAdapters.BillDetailsTableTableAdapter _Adt_Details;
        private DatabaseDataSetTableAdapters.BillMainTableTableAdapter _Adt_Main;
        private bool _Database_Is_Blank = false;
        private bool _First_Check_Duplicate_Bill_No = false;
        private int _Current_BillNo_Int = 0;
        private string _Current_BillNo = "";
        public  int MaxLengthOfServiceNameColumm = 18;
    

        // constructor
        public BillManagement(DatabaseDataSet dt)
        {
            _Dataset = dt;
            _DataTable_Details = _Dataset.BillDetailsTable;
            _DataTable_Main = _Dataset.BillMainTable;

            _Adt_Details = new DatabaseDataSetTableAdapters.BillDetailsTableTableAdapter();
            _Adt_Main = new DatabaseDataSetTableAdapters.BillMainTableTableAdapter();

            LoadDB(TABLE_TYPE.DETAILS);
        }

        // property / field
        public string Room = "";
        public int Voucher = 0;
        public int Tips = 0;
        public string Cashier = "";
        public string Customer = "";
        public string CustomerID = "";
        public int VND = 0;
        public int USD = 0;
        public int Card = 0;
        public int Total = 0;
        public string StaffNo = "";
   
        public List<string> ServiceNameList = new List<string>();

        public string Current_BillNumber
        {
            get { return _Current_BillNo;}
            set 
            {
                string s = value;
                if (s != Current_BillNumber)
                {
                    int.TryParse(s, out _Current_BillNo_Int);
                    _Current_BillNo = s;
                }
            }
        }
        private int count_details
        {
            get { return _DataTable_Details.Rows.Count; }
        }

        // method
        public string Create_New_BillNo()
        {
            try
            {
                DatabaseDataSet.BillDetailsTableDataTable table_temp = new DatabaseDataSet.BillDetailsTableDataTable();
                int maxID = (int)_Adt_Details.GetIDMax();
                _Adt_Details.FillByID(table_temp, maxID);
                if (table_temp[0].BillNo != Current_BillNumber)
                    return Current_BillNumber;
            }
            catch (Exception)
            {
                return Current_BillNumber;
            }

            _Current_BillNo_Int++;
            _Current_BillNo = InsertZeroForBillNo();

            Voucher = 0;
            USD = 0;
            VND = 0;
            Card = 0;
            Total = 0;
            Tips = 0;
            Customer = "";
            CustomerID = "";
            Room = "";
            StaffNo = "";

            ServiceNameList.Clear();
            return Current_BillNumber;
        }

        private string InsertZeroForBillNo()
        {
            string s="";
            if (_Current_BillNo_Int < 10) s = "00000" + _Current_BillNo_Int.ToString();
            if ((_Current_BillNo_Int >= 10) && (_Current_BillNo_Int < 100)) s = "0000" + _Current_BillNo_Int.ToString();
            if ((_Current_BillNo_Int >= 100) && (_Current_BillNo_Int < 1000)) s = "000" + _Current_BillNo_Int.ToString();
            if ((_Current_BillNo_Int >= 1000) && (_Current_BillNo_Int < 10000)) s = "00" + _Current_BillNo_Int.ToString();
            if ((_Current_BillNo_Int >= 10000) && (_Current_BillNo_Int < 100000)) s = "0" + _Current_BillNo_Int.ToString();
            if (_Current_BillNo_Int >= 100000) s = _Current_BillNo_Int.ToString();
            return s;
            
        }

        public bool AddNewRowToBillDtails(string ServiceName, string ServiceID, int Quanlity, int PricePerUnit, int Discount, bool IsPercent, string Notes)
        {
            if (!_First_Check_Duplicate_Bill_No)
            {
                CheckForDuplicateBillNo();
                _First_Check_Duplicate_Bill_No = true;
            }
            // Check Full Bill or not
            int temp = 0;
            for (int j = 0; j < ServiceNameList.Count; j++) 
                if (ServiceNameList[j].Length > MaxLengthOfServiceNameColumm) temp += 2;
                else temp += 1;
            if (ServiceName.Length > MaxLengthOfServiceNameColumm) temp += 2;
            else temp += 1;
 
            if (temp > 6)
            {
                
                MessageBox.Show("Bill is full, can not add more services in this bill !", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                return false;
            }

            // add new rows if Bill does not full
            DataRow NewRows =  _DataTable_Details.NewRow();
            NewRows["BillNo"] = Current_BillNumber;
            NewRows["ServiceID"] = ServiceID;
            NewRows["Quantity"] = Quanlity;
            NewRows["PricePerUnit"] = PricePerUnit;
            NewRows["Discount"] = Discount;
            NewRows["Notes"] = Notes;
            NewRows["Percent"] = IsPercent;
            NewRows["Price"] = CalPriceForEachService(PricePerUnit, Quanlity, Discount, IsPercent);
            NewRows["Notes"] = Notes;
            ServiceNameList.Add(ServiceName);

            _DataTable_Details.Rows.Add(NewRows);

            return true;
        } // insert to DataTable of dataset
        public void DeleteLastRow()
        {
            _DataTable_Details.RemoveBillDetailsTableRow(_DataTable_Details[_DataTable_Details.Rows.Count-1]);
            ServiceNameList.RemoveAt(ServiceNameList.Count - 1);
        }
        private int CalPriceForEachService(int PricePerUnit, int Quantity, int Discount, bool Percent)
        {
            int price = 0;
            if (Percent == true) price = (PricePerUnit * Quantity) * (100 - Discount) / 100;
            else price = (PricePerUnit- Discount) * Quantity ;
            return price;
        }

        public void ApplyTotalDiscount(int TotalDiscount)
        {
            int count = _DataTable_Details.Rows.Count;
            for (int j = 0; j < count; j++)
            {
                _DataTable_Details[j].Discount = TotalDiscount;
                _DataTable_Details[j].Percent = true;
                _DataTable_Details[j].Price = CalPriceForEachService(_DataTable_Details[j].PricePerUnit, _DataTable_Details[j].Quantity, _DataTable_Details[j].Discount, _DataTable_Details[j].Percent);
            }
        }

        public int GetTotal()
        {
            int Total = 0;
            for (int j = 0; j < _DataTable_Details.Rows.Count; j++) Total += _DataTable_Details[j].Price;

            Total += Tips - Voucher;
            this.Total = Total;
            return Total;
        }
        public int GetRawTotalForPrintingBill()
        {
            int result = 0;
            for (int j = 0; j < count_details; j++)
                result += _DataTable_Details[j].PricePerUnit * _DataTable_Details[j].Quantity;
            return result;
        }
        public int GetTotalDiscountForPrintingBill()
        {
            int result = 0;
            for (int j = 0; j < count_details; j++)
                result += - _DataTable_Details[j].Price + _DataTable_Details[j].PricePerUnit * _DataTable_Details[j].Quantity;
            return result;
        }
       
        public int GetReturn(int ExchangeRate)
        {
            int result = 0;

            result = USD * ExchangeRate + VND + Card - GetTotal();

            return result;
        }

        public void ClearDataTableBill()
        {
            _DataTable_Details.Clear();
            _DataTable_Main.Clear();

            _DataTable_Details.Columns["ID"].AutoIncrementSeed = -1; // neccessary to do 2 statements
            _DataTable_Details.Columns["ID"].AutoIncrementStep = -1;

            _DataTable_Details.Columns["ID"].AutoIncrementSeed = 1;
            _DataTable_Details.Columns["ID"].AutoIncrementStep = 1;

            _First_Check_Duplicate_Bill_No = false;
        }

        private bool CheckForDuplicateBillNo()
        {
            bool bDuplicate = false;

            try
            {
                DatabaseDataSet.BillDetailsTableDataTable temp = new DatabaseDataSet.BillDetailsTableDataTable();
                int maxID = (int)_Adt_Details.GetIDMax();
                _Adt_Details.FillByID(temp, maxID);
                if (Current_BillNumber == temp[0].BillNo) bDuplicate = true;
            }
            catch (Exception)
            {
                _Database_Is_Blank = true;
            }

            return bDuplicate;
        }

        // this method used for upload new bill to DB : use it often
        public bool InsertNewBillToDB()
        {
            bool bError = false;
            // insert some rows of BillDetails to DB
            int count = _DataTable_Details.Rows.Count;
            if (count > 0)
            {
                for (int j = 0; j < count; j++)
                {
                    _Adt_Details.InsertNewBill(Current_BillNumber, _DataTable_Details[j].ServiceID, _DataTable_Details[j].PricePerUnit, _DataTable_Details[j].Quantity, _DataTable_Details[j].Price, _DataTable_Details[j].Discount, _DataTable_Details[j].Percent, _DataTable_Details[j].Notes);
                }

                // insert 1 row of BillMain to DB
                _Adt_Main.InsertNewBill(Current_BillNumber, Room, Voucher, Cashier, Customer, VND, USD, Card, Total, DateTime.Now, Tips, CustomerID, StaffNo);
            }
            else bError = true;

            _First_Check_Duplicate_Bill_No = false;

            return bError;
        }

        private void LoadDB(TABLE_TYPE tp)
        {
            if (tp == TABLE_TYPE.DETAILS)
            {
                try
                {
                    int maxID = (int)_Adt_Details.GetIDMax();
                    _Adt_Details.FillByID(_DataTable_Details, maxID);
                    _Current_BillNo = _DataTable_Details[0].BillNo;

                    int.TryParse(_Current_BillNo, out _Current_BillNo_Int);
                    _Current_BillNo_Int++;
                    _Current_BillNo = InsertZeroForBillNo();
                    ClearDataTableBill();
                }
                catch (Exception)
                {
                    _Current_BillNo_Int = 0;
                    Current_BillNumber = "000000";
                    _Database_Is_Blank = true;
                }
            }
            else
            {
                _Adt_Main.Fill(_DataTable_Main);
            }
        }     // use it to know Current Bill Number in system

        // dont use anymore

        private void UpdateDB(TABLE_TYPE tp)
        {
            try
            {
                if (tp == TABLE_TYPE.DETAILS) _Adt_Details.Update(_DataTable_Details);
                else _Adt_Main.Update(_DataTable_Main);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }  // no needs to use this method, we use Insert instead of Update

        /*        public string CreateNewBillNumber()
                {
                    // clear any thing concerned with last bill
                    Voucher = 0;
                    VND = 0;
                    USD = 0;
                    Card = 0;
                    Total = 0;
                    // after update to DB, we need to ecrase Data Table in dataset
                    ClearDataTableBill();
                    _DataTable_Details.Columns["ID"].AutoIncrementSeed = -1; // neccessary to do 2 statements
                    _DataTable_Details.Columns["ID"].AutoIncrementStep = -1;

                    _DataTable_Details.Columns["ID"].AutoIncrementSeed = 1;
                    _DataTable_Details.Columns["ID"].AutoIncrementStep = 1;

                    //check whether Bill Number already existed on Bill Details Table or not
                    // if not, return
                    // if yes, create new number
                    try
                    {
                        DatabaseDataSet.BillDetailsTableDataTable table_temp = new DatabaseDataSet.BillDetailsTableDataTable();
                        int maxID = (int)_Adt_Details.GetIDMax();
                        _Adt_Details.FillByID(table_temp, maxID);
                        if (table_temp[0].BillNo != Current_BillNumber)
                            return Current_BillNumber;
                    }
                    catch (Exception)
                    {
                        return Current_BillNumber;
                    }

                    // create new bill number
                    string BillNumber = "";// = DateTime.Now.Month.ToString();

                    if (DateTime.Now.Month < 10) BillNumber = "0" + DateTime.Now.Month.ToString();
                    else BillNumber = DateTime.Now.Month.ToString();

                    if (DateTime.Now.Day < 10) BillNumber += "0" + DateTime.Now.Day.ToString();
                    else BillNumber += DateTime.Now.Day.ToString();

                    _Init_BillNumber++;

                    if (_Init_BillNumber < 10) BillNumber += "00" + _Init_BillNumber.ToString();
                    if ((_Init_BillNumber >= 10) && (_Init_BillNumber < 100)) BillNumber += "0" + _Init_BillNumber.ToString();
                    if (_Init_BillNumber >= 100) BillNumber += _Init_BillNumber.ToString();

                    Current_BillNumber = BillNumber;

                    return BillNumber;
                }

                  private void Init_BillNumber()
                {
                    // Bill Number Frame: MMDDXXX
                    // MM : month
                    // DD : day of month
                    // XXX : sequence of bill 

                    // find last row in BillDetailsTable in DB
                    if (_Database_Is_Blank == false)
                    {
                        var query = (from q in _DataTable_Details
                                     orderby _DataTable_Details.IDColumn
                                     select new { q.BillNo }).Last();
                        // if the length of BillNo != 7 OF = null, return : when database dont has any rows or garbage rows
                        if ((query.BillNo.Length != 7) || (query.BillNo == null))
                        {
                            _Init_BillNumber = 0;
                            return;
                        }
                        // init for BillNumber         
                        int iDay = 0;
                        int.TryParse(query.BillNo.Substring(2, 2), out iDay);
                        if (iDay != DateTime.Now.Day) _Init_BillNumber = 0;
                        else int.TryParse(query.BillNo.Substring(4), out _Init_BillNumber);

                        // clear _DataTable_Details : no need 
                        _DataTable_Details.Clear();
                    }
                    else _Init_BillNumber = 0;
                }
       
                */


    }

    public class Bill_Template_For_Email
    { 
        public Bill_Template_For_Email()
        {

        }
    }
}
